﻿// -----------------------------------------------------------------------
// <copyright file="NinjectDependencyResolver.cs" company="EPAM Systems">
////Copyright (c) EPAM Systems, 2012. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------

namespace MBOP.Website.Infrastructure
{
	#region Usings

	using System;
	using System.Collections.Generic;
	using System.Web.Mvc;

	using MBOP.Configuration.ConfigElements;
	using MBOP.Core.Interfaces.DataProviders;
	using MBOP.Core.Interfaces.Managers;
	using MBOP.Core.Interfaces.Notification;
	using MBOP.Core.Interfaces.Services;
	using MBOP.Core.Interfaces.TextTemplatesCore;
	using MBOP.DataAccess.DataProviders;
	using MBOP.Domain.Managers;
	using MBOP.Domain.Services;
	using MBOP.Notification.Services;
	using Ninject;
	using TextTemplatesCore.Concrete;

	#endregion

	/// <summary>
	/// The <see cref="IDependencyResolver"/> implementer
	/// which resolve application dependencies using DI container.
	/// </summary>
	public class NinjectDependencyResolver : IDependencyResolver, IDisposable
	{
		#region Private Fields
		/// <summary>
		/// Represents the kernel of the DI container.
		/// </summary>
		private IKernel _ninjectKernel;

		#endregion

		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="NinjectDependencyResolver"/> class.
		/// </summary>
		public NinjectDependencyResolver()
		{
			this._ninjectKernel=new StandardKernel();
			this.SetBindings();
		}

		#endregion

		#region Properties

		public IKernel Kernel 
		{
			get { return _ninjectKernel; }
		}

		#endregion

		#region IDependencyResolver Members

		/// <summary>
		/// Retrieves a service from the scope.
		/// </summary>
		/// <param name="serviceType">The service to be retrieved.</param>
		/// <returns>The retrieved service.</returns>
		public object GetService(Type serviceType)
		{
			return _ninjectKernel.TryGet(serviceType);
		}

		/// <summary>
		/// Retrieves a collection of services from the scope.
		/// </summary>
		/// <param name="serviceType">The collection of services to be retrieved.</param>
		/// <returns>The retrieved collection of services.</returns>
		public IEnumerable<object> GetServices(Type serviceType)
		{
			return _ninjectKernel.GetAll(serviceType);
		}

		#endregion

		#region Private Fields

		/// <summary>
		/// Sets container bindings.
		/// </summary>
		private void SetBindings()
		{
			_ninjectKernel.Bind<IBookDataProvider>().To<BookDataProvider>();
			_ninjectKernel.Bind<IImageDataProvider>().To<ImageDataProvider>();
			_ninjectKernel.Bind<IActiveDirectoryDataProvider>().To<ActiveDirectoryDataProvider>();
			
			_ninjectKernel.Bind<ICacheManager>().To<WebCacheManager>();

			_ninjectKernel.Bind<IBookService>().To<BookService>();
			_ninjectKernel.Bind<IPersonInformationService>().To<PersonInformationService>();
			_ninjectKernel.Bind<IImageService>().To<ImageService>();
			_ninjectKernel.Bind<INotificationService>().To<NotificationService>();

			_ninjectKernel.Bind<INotificationEngine>().To<MailNotificationEngine>();

			_ninjectKernel.Bind<ITemplateResolver>().To<NVelocityTemplateResolver>();

			_ninjectKernel.Bind<EmailServiceElement>()
				.ToConstant(AppConfigurationSection.GetInstance().NotificationServices.EmailService);

			_ninjectKernel.Bind<NotificationServicesElement>()
				.ToConstant(AppConfigurationSection.GetInstance().NotificationServices);
		}

		#endregion

		#region IDisposable Implementation

		public void Dispose()
		{
			this._ninjectKernel.Dispose();
		}

		#endregion
	}
}